package com.ruoyi.web.controller.app.service;

import com.ruoyi.framework.web.exception.base.XException;
import com.ruoyi.sj.domain.*;
import com.ruoyi.sj.mapper.*;
import com.ruoyi.util.SerialNumber;
import com.ruoyi.web.controller.app.intercepter.FilterAnnotation;
import com.ruoyi.web.controller.app.request.RequestSendBedEntity;
import com.ruoyi.web.controller.pay.PayComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName AppSendRedService
 * @Description TODO
 * @Author tyc@yanyu
 * @Date 2018/12/28 0028 10:59
 **/
@Service
public class AppSendRedService {

    private SerialNumber serial = new SerialNumber("HB");

    @Autowired
    private MoneyMapper moneyMapper;
    @Autowired
    private RedReceiveMapper redReceiveMapper;
    @Autowired
    private SendRedMapper sendRedMapper;
    @Autowired
    private PayComponent payComponent;

    @Transactional
    @FilterAnnotation(validator = true)
    public Object userSendReds(RequestSendBedEntity entity) {
        //生成发送红包信息
        SendRed sendRed = new SendRed();
        sendRed.setMoney(entity.getMoney());
        sendRed.setNum(entity.getCount());
        sendRed.setSenderID(entity.getMemberId().toString());
        sendRed.setType(entity.getType());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sendRed.setSendDate(sdf.format(new Date()));
        sendRed.setNote(entity.getNote());
        //持久化发送红包信息
        sendRedMapper.insertSendRed(sendRed);

        BigDecimal decimalMoney = new BigDecimal(entity.getMoney());
        List<BigDecimal> moneys = math(decimalMoney, entity.getCount());
        if (moneys == null || moneys.size() == 0) throw new XException("金额数量不匹配");
        RedReceive redReceive = new RedReceive();
        //瓜分红包
        for (BigDecimal bigDecimal : moneys) {
            redReceive.setRecMoney(String.valueOf(bigDecimal));
            redReceive.setRedId(sendRed.getId());
            redReceive.setType(entity.getType());
            redReceive.setStatus(0);
            redReceiveMapper.insertRedReceive(redReceive);
        }

        //生成订单
        Order order = new Order();
        order.setSn(serial.getAtomicNumber());//生成订单号
        order.setType(entity.getType());
        order.setMemberId(entity.getMemberId().toString());
        order.setCreateDate(new Date());
        order.setTitle(entity.getType() == 3 ? "红包" : "金包");
        order.setPayMoney(entity.getMoney());
        order.setPayType(entity.getPayType());
        order.setGoodsId(sendRed.getId().toString());
        order.setPayPassword(entity.getPayPassword());
        payComponent.sendToPay(order);
        return order;
    }

    /**
     * 计算每人获得红包金额;最小每人0.01元
     *
     * @param mmm    红包总额
     * @param number 人数
     * @return
     */
    public List<BigDecimal> math(BigDecimal mmm, int number) {
        if (mmm.doubleValue() < number * 0.01) {
            return null;
        }
        Random random = new Random();
        // 金钱，按分计算 10块等于 1000分
        int money = mmm.multiply(BigDecimal.valueOf(100)).intValue();
        // 随机数总额
        double count = 0;
        // 每人获得随机点数
        double[] arrRandom = new double[number];
        // 每人获得钱数
        List<BigDecimal> arrMoney = new ArrayList<BigDecimal>(number);
        // 循环人数 随机点
        for (int i = 0; i < arrRandom.length; i++) {
            int r = random.nextInt((number) * 99) + 1;
            count += r;
            arrRandom[i] = r;
        }
        // 计算每人拆红包获得金额
        int c = 0;
        for (int i = 0; i < arrRandom.length; i++) {
            // 每人获得随机数相加 计算每人占百分比
            Double x = new Double(arrRandom[i] / count);
            // 每人通过百分比获得金额
            int m = (int) Math.floor(x * money);
            // 如果获得 0 金额，则设置最小值 1分钱
            if (m == 0) {
                m = 1;
            }
            // 计算获得总额
            c += m;
            // 如果不是最后一个人则正常计算
            if (i < arrRandom.length - 1) {
                arrMoney.add(new BigDecimal(m).divide(new BigDecimal(100)));
            } else {
                // 如果是最后一个人，则把剩余的钱数给最后一个人
                arrMoney.add(new BigDecimal(money - c + m).divide(new BigDecimal(100)));
            }
        }
        // 随机打乱每人获得金额
        Collections.shuffle(arrMoney);
        return arrMoney;
    }

    /**
     * @param memberId
     * @param redId
     * @return
     */
    @Transactional(readOnly = false)
    public Object receiveRed(Long memberId, Integer redId) {
        SendRed sendRed = sendRedMapper.selectSendRedById(redId);
        if (sendRed == null || sendRed.getType() == null) throw new XException("红包不存在了");
        try {
            // 抢红包
            int count = redReceiveMapper.receiveRed(memberId, redId);
            if (count < 0) throw new XException("红包已抢光");
            String recMoney = redReceiveMapper.selectMoney(memberId, redId);
            // 提现到余额
            if (sendRed.getType() == 3) moneyMapper.addMoney(String.valueOf(memberId), recMoney);
            return recMoney;
        } catch (DuplicateKeyException e) {
            throw new XException("你已经领过红包了");
        }
    }

    /**
     * 查询用户信息
     * @param redId
     * @return
     */
    public Object getUserByRedId(Integer redId) {
        if (redId==null){
            throw new XException("红包id不能为空");
        }
        return sendRedMapper.getUserByRedId(redId);
    }
}
